package com.ts.animal.service.impl;

import com.alibaba.fastjson.JSON;
import com.ts.animal.constant.AnimalConstant;
import com.ts.animal.dao.*;
import com.ts.animal.domain.*;
import com.ts.animal.service.WarningRecordService;
import com.ts.common.redis.RedisUtil;
import com.ts.common.utils.*;
import com.ts.system.util.SystemUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


@Service
public class WarningRecordServiceImpl implements WarningRecordService {

    private static Logger log = LoggerFactory.getLogger(WarningRecordServiceImpl.class);
    @Autowired
    private WarningRecordDao warningRecordDao;
    @Autowired
    private ExWarningRecordDao exWarningRecordDao;
    @Autowired
    private ExBaseStationDao exBaseStationDao;
    @Autowired
    private ExHeartbeatRecordDao exHeartbeatRecordDao;
    @Autowired
    private ExRfidSyncDataDao exRfidSyncDataDao;
    @Autowired
    SimpMessagingTemplate template;

    @Override
    public WarningRecordDO get(Integer id) {
        return warningRecordDao.get(id);
    }

    @Override
    public List<Map<String, Object>> list(Map<String, Object> map) {
        map.putAll(DataPerUitl.deptPer("bi.dept_id"));
        return exWarningRecordDao.list(map);
    }

    @Override
    public int count(Map<String, Object> map) {
        map.putAll(DataPerUitl.deptPer("bi.dept_id"));
        return exWarningRecordDao.count(map);
    }

    @Override
    public int save(Result result, WarningRecordDO warningRecord) {
        int ret = warningRecordDao.save(warningRecord);
        if (ret == 0) {
            result.set(Result.FAIL, "保存失败", null);
        }
        return ret;


    }

    @Override
    public int update(Result result, WarningRecordDO warningRecord) {
        int ret = warningRecordDao.update(warningRecord);
        if (ret == 0) {
            result.set(Result.FAIL, "更新失败", null);
        }
        return ret;
    }

    @Override
    public int remove(Result result, Integer id) {
        int ret = warningRecordDao.remove(id);
        if (ret == 0) {
            result.set(Result.FAIL, "删除失败", null);
        }
        return ret;
    }

    @Override
    public int batchRemove(Result result, Integer[] ids) {
        int ret = warningRecordDao.batchRemove(ids);
        if (ret != ids.length) {
            result.set(Result.FAIL, "部分删除失败", null);
        }
        return ret;
    }

    //预警任务调度  调用方法
    @Override
    public void warning() {
        List<WarningRecordDO> warningRecordDOList = new ArrayList<WarningRecordDO>();
        int lastMaxId = 0;
        try {
            String maxIdStr = RedisUtil.get(AnimalConstant.REDIS_BASE_WARNING_MAX_ID);
            log.info("从redis获取-REDIS_BASE_WARNING_MAX_ID：{}", maxIdStr);
            if (StringUtils.isEmpty(maxIdStr)) {
                lastMaxId = exBaseStationDao.fixDayMinSyncId();
                log.info("从数据库中获取（前五天）lastMaxId：{}", lastMaxId);
            } else {
                lastMaxId = Integer.parseInt(maxIdStr);
            }

            List<ExRfidSyncDataDO> list = exBaseStationDao.getNotWarnSyncData(lastMaxId);
            //log.info("从数据库中获取动物体温等数据List：{}", JSON.toJSONString(list));
            for (ExRfidSyncDataDO exRfidSyncDataDO : list) {

                lastMaxId = (int) exRfidSyncDataDO.getId().longValue();
                Date now = new Date();
                //动物生日
                Date birthday = exRfidSyncDataDO.getBirthday();
                //最后配种时间
                Date lastBreedTime = exRfidSyncDataDO.getLastBreedTime();
                //动物当前体温
                Float bodyTemperature = exRfidSyncDataDO.getBodyTemperature();
                //动物品种
                String varietyName = exRfidSyncDataDO.getVarietyName() == null ? "" : exRfidSyncDataDO.getVarietyName();
                log.info("动物信息----动物品种：{}，动物芯片号：{}，动物体温：{}，动物生日：{},动物最后配种日期：{}", varietyName, exRfidSyncDataDO.getNum(), bodyTemperature, birthday, lastBreedTime);


                ExWarningSetDO exWarningSetDO = SystemUtil.getWarningSets().get(null);
                // 没有指定品种的预警参数设置 所以取默认
//                if (exWarningSetDO == null && StringUtils.isNotEmpty(varietyName)) {
//                    log.info("品种{}没有配置预警参数，取默认预警参数", varietyName);
//                    //所以取默认
//                    exWarningSetDO = SystemUtil.getWarningSets().get("");
//                }
//                //默认预警参数也没有
//                if (exWarningSetDO == null) {
//                    log.info("品种{}未配置预警参数，也没有默认预警参数，所以不判断预警", varietyName);
//                    continue;
//                }

                //疾病参数
                Float sickLowerBodyTemperature = exWarningSetDO.getWarningSet().getSick().getLowerBodyTemperature();
                Float sickUpperBodyTemperature = exWarningSetDO.getWarningSet().getSick().getUpperBodyTemperature();
                //发情参数
                Integer oestrusStartBirthday = exWarningSetDO.getWarningSet().getOestrus().getStartBirthday();
                Integer oestrusEndBirthday = exWarningSetDO.getWarningSet().getOestrus().getEndBirthday();
                //生产参数
                Float parturitionUpperBodyTemperature = exWarningSetDO.getWarningSet().getParturition().getUpperBodyTemperature();
                //距离配种日期最小天数 开始预警
                Integer parturitionStartHybridizationDa = exWarningSetDO.getWarningSet().getParturition().getStartHybridizationDay();
                Integer parturitionEndHybridizationDa = exWarningSetDO.getWarningSet().getParturition().getEndHybridizationDay();


                //疾病下限体温  体温过低  疾病 01
                if ((sickLowerBodyTemperature != null && bodyTemperature <= sickLowerBodyTemperature)) {
                    log.info("疾病预警--动物信息----动物品种：{}，动物芯片号：{}，动物体温：{}，动物生日：{},动物最后配种日期：{}", varietyName, exRfidSyncDataDO.getNum(), bodyTemperature, birthday, lastBreedTime);
                    log.info("疾病预警参数----疾病下限体温：{}，疾病上限体温：{}", sickLowerBodyTemperature, sickUpperBodyTemperature);
                    String result = String.format("牲畜体温为%s°C，可能已经生病，请及时处理", String.valueOf(bodyTemperature));
                    //TODO 入库
                    WarningRecordDO warningRecordDO = new WarningRecordDO();
                    warningRecordDO.setBaseStationNum(exRfidSyncDataDO.getBaseStationNum());
                    warningRecordDO.setNum(exRfidSyncDataDO.getNum());
                    warningRecordDO.setWarningDesc(result);
                    warningRecordDO.setWarningType(AnimalConstant.warning_type_sick);
                    warningRecordDO.setWarningTime(now);
                    warningRecordDO.setRemark1(warningRecordDO.getWarningType() + warningRecordDO.getNum() + warningRecordDO.getWarningTime().getTime());
                    if (!AnimalConstant.open.equals(exWarningSetDO.getDialogTipSwitch())) {
                        warningRecordDO.setHandler(1l);
                        warningRecordDO.setHandlingTime(new Date());
                        warningRecordDO.setHandlingResult("弹窗开关未打开，默认已处理");
                    }
//                    warningRecordDao.save(warningRecordDO);
                    warningRecordDOList.add(warningRecordDO);
                }

                //距离生日最小天数 开始预警  发情 02
                if (birthday != null) {//TODO 需要再加上动物性别
                    int intervalDays = UtilDate.getIntervalDays(birthday, now);
                    if (intervalDays >= oestrusStartBirthday && intervalDays <= oestrusEndBirthday) {
                        log.info("发情预警--动物信息----动物品种：{}，动物芯片号：{}，动物体温：{}，动物生日：{},动物最后配种日期：{}", varietyName, exRfidSyncDataDO.getNum(), bodyTemperature, birthday, lastBreedTime);
                        log.info("发情预警参数----发情距离生日最小天数：{}，发情距离生日最大天数：{}", oestrusStartBirthday, oestrusEndBirthday);
                        String result = String.format("牲畜已达%d日龄，达到发情期，请及时处理", intervalDays);
                        //TODO 入库
                        WarningRecordDO warningRecordDO = new WarningRecordDO();
                        warningRecordDO.setBaseStationNum(exRfidSyncDataDO.getBaseStationNum());
                        warningRecordDO.setNum(exRfidSyncDataDO.getNum());
                        warningRecordDO.setWarningDesc(result);
                        warningRecordDO.setWarningType(AnimalConstant.warning_type_oestrus);
                        warningRecordDO.setWarningTime(now);
                        warningRecordDO.setRemark1(warningRecordDO.getWarningType() + warningRecordDO.getNum() + warningRecordDO.getWarningTime().getTime());
                        if (!AnimalConstant.open.equals(exWarningSetDO.getDialogTipSwitch())) {
                            warningRecordDO.setHandler(1l);
                            warningRecordDO.setHandlingTime(new Date());
                            warningRecordDO.setHandlingResult("弹窗开关未打开，默认已处理");
                        }
                        //                    warningRecordDao.save(warningRecordDO);
                        warningRecordDOList.add(warningRecordDO);
                    }
                }

                //生产上限体温  生产 03
                Boolean parturitionNotNullFlag = bodyTemperature != null &&
                        lastBreedTime != null &&
                        parturitionUpperBodyTemperature != null &&
                        parturitionStartHybridizationDa != null &&
                        parturitionEndHybridizationDa != null;
                if (parturitionNotNullFlag) {
                    int intervalDays = UtilDate.getIntervalDays(lastBreedTime, now);
                    Boolean parturitionTrueFag = intervalDays >= parturitionStartHybridizationDa && intervalDays <= parturitionEndHybridizationDa && bodyTemperature >= parturitionUpperBodyTemperature;
                    if (parturitionTrueFag) {
                        log.info("生产预警--动物信息----动物品种：{}，动物芯片号：{}，动物体温：{}，动物生日：{},动物最后配种日期：{}", varietyName, exRfidSyncDataDO.getNum(), bodyTemperature, birthday, lastBreedTime);
                        log.info("生产预警参数----生产上限体温：{}，生产距配种最小天数：{}，生产距配种最大天数：{}", parturitionUpperBodyTemperature, parturitionStartHybridizationDa, parturitionEndHybridizationDa);
                        //TODO 入库  并不再直接进入下一个循环;
                        String result = String.format("牲畜体温为%s°C,距配种期%d天，可能即将生产，请及时处理", String.valueOf(bodyTemperature), intervalDays);
                        WarningRecordDO warningRecordDO = new WarningRecordDO();
                        warningRecordDO.setBaseStationNum(exRfidSyncDataDO.getBaseStationNum());
                        warningRecordDO.setNum(exRfidSyncDataDO.getNum());
                        warningRecordDO.setWarningDesc(result);
                        warningRecordDO.setWarningType(AnimalConstant.warning_type_parturition);
                        warningRecordDO.setWarningTime(now);
                        warningRecordDO.setRemark1(warningRecordDO.getWarningType() + warningRecordDO.getNum() + warningRecordDO.getWarningTime().getTime());
                        if (!AnimalConstant.open.equals(exWarningSetDO.getDialogTipSwitch())) {
                            warningRecordDO.setHandler(1l);
                            warningRecordDO.setHandlingTime(new Date());
                            warningRecordDO.setHandlingResult("弹窗开关未打开，默认已处理");
                        }
                        //                    warningRecordDao.save(warningRecordDO);
                        warningRecordDOList.add(warningRecordDO);
                        continue;
                    }
                }

                //疾病下限体温  疾病 体温过高 04
                if (sickUpperBodyTemperature != null && bodyTemperature >= sickUpperBodyTemperature) {
                    log.info("疾病--动物信息----动物品种：{}，动物芯片号：{}，动物体温：{}，动物生日：{},动物最后配种日期：{}", varietyName, exRfidSyncDataDO.getNum(), bodyTemperature, birthday, lastBreedTime);
                    log.info("疾病预警参数----疾病下限体温：{}，疾病上限体温：{}", sickLowerBodyTemperature, sickUpperBodyTemperature);
                    String result = String.format("牲畜体温为%s°C，可能已经生病，请及时处理", String.valueOf(bodyTemperature));
                    //TODO 入库
                    WarningRecordDO warningRecordDO = new WarningRecordDO();
                    warningRecordDO.setBaseStationNum(exRfidSyncDataDO.getBaseStationNum());
                    warningRecordDO.setNum(exRfidSyncDataDO.getNum());
                    warningRecordDO.setWarningDesc(result);
                    warningRecordDO.setWarningType(AnimalConstant.warning_type_sick);
                    warningRecordDO.setWarningTime(now);
                    warningRecordDO.setRemark1(warningRecordDO.getWarningType() + warningRecordDO.getNum() + warningRecordDO.getWarningTime().getTime());
                    if (!AnimalConstant.open.equals(exWarningSetDO.getDialogTipSwitch())) {
                        warningRecordDO.setHandler(1l);
                        warningRecordDO.setHandlingTime(new Date());
                        warningRecordDO.setHandlingResult("弹窗开关未打开，默认已处理");
                    }
                    //                    warningRecordDao.save(warningRecordDO);
                    warningRecordDOList.add(warningRecordDO);
                }

                log.info("预警设置信息----生产上限体温：{}，生产距配种最小天数：{}，生产距配种最大天数：{}", parturitionUpperBodyTemperature, parturitionStartHybridizationDa, parturitionEndHybridizationDa);
                log.info("预警设置信息----发情距离生日最小天数：{}，发情距离生日最大天数：{}", oestrusStartBirthday, oestrusEndBirthday);
                log.info("预警设置信息----疾病上限体温：{}，疾病上限体温：{}", sickLowerBodyTemperature, sickUpperBodyTemperature);
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
        } finally {
            RedisUtil.set(AnimalConstant.REDIS_BASE_WARNING_MAX_ID, String.valueOf(lastMaxId));
            if (warningRecordDOList.size() > 0) {
                exWarningRecordDao.batchSave(warningRecordDOList);
            }
        }
    }

    //预警任务调度  调用方法
    @Override
    public void stationAndTagWarning() {
        ExWarningSetDO exWarningSetDO = SystemUtil.getWarningSets().get(null);
        //基站告警
        Map<String, WarningRecordDO> baseStationWarnRecordMap = new HashMap<String, WarningRecordDO>();
        Map<String, Object> baseStationAbnormalWarnMap = new HashMap<String, Object>();
        Map<String, ExWarningDO.NonUploadData> baseStationNonUploadWarnMap = new HashMap<String, ExWarningDO.NonUploadData>();
        Date now = new Date();
        try {
            Integer stationWarnQueryTimeSpan = Integer.valueOf(SystemUtil.getSystemParams().get(AnimalConstant.key_name_station_warn_query_time_span).getParamValue());
            Map<String, Object> params = new HashMap<>();
            params.put("startCreateTime", UtilDate.getDateBefore(now, Calendar.MINUTE, stationWarnQueryTimeSpan));
            params.put("sort", "create_time");
            params.put("order", "asc");
            List<HeartbeatRecordDO> list = exHeartbeatRecordDao.list(params);

            log.info("基站心跳数据-数量----list.size()：{}", list.size());

            //GPS天线状态 异常连续时间 分钟
            Float daGpsDuration = exWarningSetDO.getWarningSet().getStation().getDaGpsDuration();
            //GPS天线状态 异常连续时间 次数
            Float daGpsTimes = exWarningSetDO.getWarningSet().getStation().getDaGpsTimes();
            log.info("GPS天线状态告警设置----异常连续时间：{}分钟,异常连续次数：{}次", daGpsDuration, daGpsTimes);
            //市电源状态 异常连续时间 分钟
            Float daPowerDuration = exWarningSetDO.getWarningSet().getStation().getDaPowerDuration();
            //市电源状态 异常连续时间 次数
            Float daPowerTimes = exWarningSetDO.getWarningSet().getStation().getDaPowerTimes();
            log.info("市电源状态告警设置----异常连续时间：{}分钟,异常连续次数：{}次", daPowerDuration, daPowerTimes);
            //基站电池电压 异常连续时间 分钟
            Float daElecDuration = exWarningSetDO.getWarningSet().getStation().getDaElecDuration();
            //基站电池电压 异常连续时间 次数
            Float daElecTimes = exWarningSetDO.getWarningSet().getStation().getDaElecTimes();
            //基站电池电压 异常连续时间 次数
            Float daElecMin = exWarningSetDO.getWarningSet().getStation().getDaElecMin();
            log.info("基站电池电压告警设置----异常连续时间：{}分钟,异常连续次数：{}次,最小电压", daElecDuration, daElecTimes, daElecMin);
            //基站心跳数据未上传
            Float upLoadDuration = exWarningSetDO.getWarningSet().getStation().getUpLoadDuration();
            log.info("基站心跳数据未上传告警设置----持续时间：{}分钟", upLoadDuration);

            String dialogTipSwitch = exWarningSetDO.getDialogTipSwitch();
            log.info("基站告警提示开关：{}", dialogTipSwitch);


            for (int i = 0; i < list.size(); i++) {
                HeartbeatRecordDO heartbeatRecordDO = list.get(i);

                //基站异常数据 告警记录
                WarningRecordDO baseStationWarnRecord = baseStationWarnRecordMap.get(heartbeatRecordDO.getBaseStationNum());
                if (baseStationWarnRecord == null) {
                    //001 GPS天线状态
                    if (daGpsDuration != null || daGpsTimes != null) {
                        String gpsKey = AnimalConstant.baseStation_gps + heartbeatRecordDO.getBaseStationNum();
                        if (baseStationAbnormalWarnMap.get(gpsKey) == null) {
                            baseStationAbnormalWarnMap.put(gpsKey, new ExWarningDO.AbnormalData());
                        }
                        //GPS天线状态 异常数据
                        ExWarningDO.AbnormalData pgsAbnormalData = (ExWarningDO.AbnormalData) baseStationAbnormalWarnMap.get(gpsKey);
                        //未被记录为连续失控 且 GPS天线状态不为空  且 GPS天线状态异常的（不是1都是认为异常）
                        if (!pgsAbnormalData.getWarn() && StringUtils.isNotBlank(heartbeatRecordDO.getDaGps()) && !AnimalConstant.baseStation_arg_status_normal.equals(heartbeatRecordDO.getDaGps())) {

                            log.info("基站GPS天线状态异常告警----心跳数据：{}", JSON.toJSONString(heartbeatRecordDO));
                            //最早异常数据
                            if (pgsAbnormalData.getEarliestAbnormalTime() == null) {
                                pgsAbnormalData.setEarliestAbnormalTime(heartbeatRecordDO.getCreateTime());
                            }
                            //异常数据  且符合持续时间或者次数条件
                            pgsAbnormalData.setCurrentAbnormalTime(heartbeatRecordDO.getCreateTime());
                            pgsAbnormalData.setContinuousAbnormalTimes(pgsAbnormalData.getContinuousAbnormalTimes() + 1);
                            long realPgsDuration = (pgsAbnormalData.getCurrentAbnormalTime().getTime() - pgsAbnormalData.getEarliestAbnormalTime().getTime()) / 1000 / 60;
                            if (daGpsDuration != null && (pgsAbnormalData.getCurrentAbnormalTime().getTime() - pgsAbnormalData.getEarliestAbnormalTime().getTime() >= daGpsDuration * 1000 * 60)
                                    || daGpsTimes != null && (pgsAbnormalData.getContinuousAbnormalTimes() >= daGpsTimes)) {

                                if (daGpsDuration != null && (pgsAbnormalData.getCurrentAbnormalTime().getTime() - pgsAbnormalData.getEarliestAbnormalTime().getTime() >= daGpsDuration * 1000 * 60)) {
                                    String warnInfo = String.format("基站失控：基站%s GPS天线状态连续异常%s(超过%s)分钟，发生时间段为%s至%s",
                                            heartbeatRecordDO.getBaseStationNum(),
                                            realPgsDuration,
                                            daGpsDuration,
                                            DateUtils.format(pgsAbnormalData.getEarliestAbnormalTime(), DateUtils.DATE_TIME_PATTERN),
                                            DateUtils.format(pgsAbnormalData.getCurrentAbnormalTime(), DateUtils.DATE_TIME_PATTERN));
                                    pgsAbnormalData.setWarnInfo(warnInfo);
                                    log.info("注意：GPS天线状态异常告警----{}", warnInfo);
                                }
                                if (daGpsTimes != null && (pgsAbnormalData.getContinuousAbnormalTimes() >= daGpsTimes)) {
                                    String warnInfo = String.format("基站失控：基站%s GPS天线状态连续异常%s次，发生时间段为%s至%s",
                                            heartbeatRecordDO.getBaseStationNum(),
                                            daGpsTimes,
                                            DateUtils.format(pgsAbnormalData.getEarliestAbnormalTime(), DateUtils.DATE_TIME_PATTERN),
                                            DateUtils.format(pgsAbnormalData.getCurrentAbnormalTime(), DateUtils.DATE_TIME_PATTERN));
                                    pgsAbnormalData.setWarnInfo(warnInfo);
                                    log.info("注意：GPS天线状态异常告警----{}", warnInfo);
                                }
                                pgsAbnormalData.setWarn(true);

                                WarningRecordDO warningRecordDO = new WarningRecordDO();
                                warningRecordDO.setNum("");
                                warningRecordDO.setBaseStationNum(heartbeatRecordDO.getBaseStationNum());
                                warningRecordDO.setWarningDesc(pgsAbnormalData.getWarnInfo());
                                warningRecordDO.setWarningTime(pgsAbnormalData.getEarliestAbnormalTime());
                                warningRecordDO.setWarningType(AnimalConstant.warning_type_baseStation);
                                warningRecordDO.setRemark1(warningRecordDO.getWarningType() + warningRecordDO.getBaseStationNum() + warningRecordDO.getWarningTime().getTime());
                                if (!AnimalConstant.open.equals(exWarningSetDO.getDialogTipSwitch())) {
                                    warningRecordDO.setHandler(1l);
                                    warningRecordDO.setHandlingTime(new Date());
                                    warningRecordDO.setHandlingResult("弹窗开关未打开，默认已处理");
                                }
                                //warningRecordDao.save(warningRecordDO);
                                //记录到MAP
                                baseStationWarnRecordMap.put(heartbeatRecordDO.getBaseStationNum(), warningRecordDO);

                            } else {
                                log.info("基站{}GPS天线状态数据异常,但是未满足所需告警条件，当前GPS天线状态已经持续异常{}次，当前GPS天线状态已经持续异常{}分钟，", heartbeatRecordDO.getBaseStationNum(), pgsAbnormalData.getContinuousAbnormalTimes(), realPgsDuration);
                                log.info("基站{}GPS天线状态异常告警需持续异常{}次或者持续异常{}分钟，", heartbeatRecordDO.getBaseStationNum(), daGpsTimes, daGpsDuration);
                            }
                        } else {//数据正常
                            pgsAbnormalData.setEarliestAbnormalTime(null);
                            pgsAbnormalData.setContinuousAbnormalTimes(0);
                        }
                    }


                    //002 市电源状态
                    if (daPowerDuration != null || daPowerTimes != null) {
                        String powerKey = AnimalConstant.baseStation_power + heartbeatRecordDO.getBaseStationNum();
                        if (baseStationAbnormalWarnMap.get(powerKey) == null) {
                            baseStationAbnormalWarnMap.put(powerKey, new ExWarningDO.AbnormalData());
                        }
                        //市电源状态 异常数据
                        ExWarningDO.AbnormalData powerAbnormalData = (ExWarningDO.AbnormalData) baseStationAbnormalWarnMap.get(powerKey);
                        //未被记录为连续失控 且 市电源状态不为空  且 市电源状态异常的（不是1都是认为异常）
                        if (!powerAbnormalData.getWarn() && StringUtils.isNotBlank(heartbeatRecordDO.getDaPower()) && !AnimalConstant.baseStation_arg_status_normal.equals(heartbeatRecordDO.getDaPower())) {
                            log.info("基站市电源状态异常告警----心跳数据：{}", JSON.toJSONString(heartbeatRecordDO));
                            //最早异常数据
                            if (powerAbnormalData.getEarliestAbnormalTime() == null) {
                                powerAbnormalData.setEarliestAbnormalTime(heartbeatRecordDO.getCreateTime());
                            }
                            //当前异常数据
                            powerAbnormalData.setCurrentAbnormalTime(heartbeatRecordDO.getCreateTime());
                            powerAbnormalData.setContinuousAbnormalTimes(powerAbnormalData.getContinuousAbnormalTimes() + 1);
                            long realPowerDuration = (powerAbnormalData.getCurrentAbnormalTime().getTime() - powerAbnormalData.getEarliestAbnormalTime().getTime()) / 1000 / 60;
                            if (daPowerDuration != null && (powerAbnormalData.getCurrentAbnormalTime().getTime() - powerAbnormalData.getEarliestAbnormalTime().getTime() >= daPowerDuration * 1000 * 60)
                                    || daPowerTimes != null && (powerAbnormalData.getContinuousAbnormalTimes() >= daPowerTimes)) {
                                powerAbnormalData.setWarn(true);

                                if (daPowerDuration != null && (powerAbnormalData.getCurrentAbnormalTime().getTime() - powerAbnormalData.getEarliestAbnormalTime().getTime() >= daPowerDuration * 1000 * 60)) {
                                    String warnInfo = String.format("基站失控：基站%s 市电源状态连续异常%s(超过%s)分钟，发生时间段为%s至%s",
                                            heartbeatRecordDO.getBaseStationNum(),
                                            realPowerDuration,
                                            daPowerDuration,
                                            DateUtils.format(powerAbnormalData.getEarliestAbnormalTime(), DateUtils.DATE_TIME_PATTERN),
                                            DateUtils.format(powerAbnormalData.getCurrentAbnormalTime(), DateUtils.DATE_TIME_PATTERN));
                                    powerAbnormalData.setWarnInfo(warnInfo);
                                    log.info("注意：市电源状态异常告警----{}", warnInfo);
                                }
                                if (daPowerTimes != null && (powerAbnormalData.getContinuousAbnormalTimes() >= daPowerTimes)) {
                                    String warnInfo = String.format("基站失控：基站%s 市电源状态连续异常%s次，发生时间段为%s至%s",
                                            heartbeatRecordDO.getBaseStationNum(),
                                            daPowerTimes,
                                            DateUtils.format(powerAbnormalData.getEarliestAbnormalTime(), DateUtils.DATE_TIME_PATTERN),
                                            DateUtils.format(powerAbnormalData.getCurrentAbnormalTime(), DateUtils.DATE_TIME_PATTERN));
                                    powerAbnormalData.setWarnInfo(warnInfo);
                                    log.info("注意：市电源状态异常告警----{}", warnInfo);
                                }

                                WarningRecordDO warningRecordDO = new WarningRecordDO();
                                warningRecordDO.setNum("");
                                warningRecordDO.setBaseStationNum(heartbeatRecordDO.getBaseStationNum());
                                warningRecordDO.setWarningDesc(powerAbnormalData.getWarnInfo());
                                warningRecordDO.setWarningTime(powerAbnormalData.getEarliestAbnormalTime());
                                warningRecordDO.setWarningType(AnimalConstant.warning_type_baseStation);
                                warningRecordDO.setRemark1(warningRecordDO.getWarningType() + warningRecordDO.getBaseStationNum() + warningRecordDO.getWarningTime().getTime());
                                if (!AnimalConstant.open.equals(exWarningSetDO.getDialogTipSwitch())) {
                                    warningRecordDO.setHandler(1l);
                                    warningRecordDO.setHandlingTime(new Date());
                                    warningRecordDO.setHandlingResult("弹窗开关未打开，默认已处理");
                                }
                                //warningRecordDao.save(warningRecordDO);
                                //记录到MAP
                                baseStationWarnRecordMap.put(heartbeatRecordDO.getBaseStationNum(), warningRecordDO);

                            } else {
                                log.info("基站{}市电源状态数据异常,但是未满足所需告警条件，当前市电源状态已经持续异常{}次，当前市电源状态已经持续异常{}分钟，", heartbeatRecordDO.getBaseStationNum(), powerAbnormalData.getContinuousAbnormalTimes(), realPowerDuration);
                                log.info("基站{}市电源状态异常告警需持续异常{}次或者持续异常{}分钟，", heartbeatRecordDO.getBaseStationNum(), daPowerTimes, daPowerDuration);
                            }
                        } else {//正常数据
                            powerAbnormalData.setEarliestAbnormalTime(null);
                            powerAbnormalData.setContinuousAbnormalTimes(0);
                        }
                    }

                    //003 基站电池电压
                    if ((daElecDuration != null || daElecTimes != null) && daElecMin != null) {
                        String elecKey = AnimalConstant.baseStation_elec + heartbeatRecordDO.getBaseStationNum();
                        if (baseStationAbnormalWarnMap.get(elecKey) == null) {
                            baseStationAbnormalWarnMap.put(elecKey, new ExWarningDO.AbnormalData());
                        }
                        //基站电池电压 异常数据
                        ExWarningDO.AbnormalData elecAbnormalData = (ExWarningDO.AbnormalData) baseStationAbnormalWarnMap.get(elecKey);
                        String daElec = heartbeatRecordDO.getDaElec();
                        Float daElecFloat = null;
                        try {
                            daElecFloat = Float.parseFloat(daElec);
                        } catch (Exception e) {
                        }
                        //未被记录为连续失控 且 基站电池电压不为空  且 基站电池电压小于最小电压
                        if (!elecAbnormalData.getWarn() && daElecFloat != null && daElecFloat < daElecMin) {
                            log.info("基站电池电压低于{}告警----心跳数据：{}", daElecMin, JSON.toJSONString(heartbeatRecordDO));
                            //最早异常数据
                            if (elecAbnormalData.getEarliestAbnormalTime() == null) {
                                elecAbnormalData.setEarliestAbnormalTime(heartbeatRecordDO.getCreateTime());
                            }
                            //当前异常数据
                            elecAbnormalData.setCurrentAbnormalTime(heartbeatRecordDO.getCreateTime());
                            elecAbnormalData.setContinuousAbnormalTimes(elecAbnormalData.getContinuousAbnormalTimes() + 1);
                            long realElecDuration = (elecAbnormalData.getCurrentAbnormalTime().getTime() - elecAbnormalData.getEarliestAbnormalTime().getTime()) / 1000 / 60;
                            if (daElecDuration != null && (elecAbnormalData.getCurrentAbnormalTime().getTime() - elecAbnormalData.getEarliestAbnormalTime().getTime() >= daElecDuration * 1000 * 60)
                                    || daElecTimes != null && (elecAbnormalData.getContinuousAbnormalTimes() >= daElecTimes)) {

                                elecAbnormalData.setWarn(true);
                                if (daElecDuration != null && (elecAbnormalData.getCurrentAbnormalTime().getTime() - elecAbnormalData.getEarliestAbnormalTime().getTime() >= daElecDuration * 1000 * 60)) {
                                    String warnInfo = String.format("基站失控：基站%s 电池电压连续%s(超过%s)分钟低于%s，发生时间段为%s至%s",
                                            heartbeatRecordDO.getBaseStationNum(),
                                            realElecDuration,
                                            daElecDuration,
                                            daElecMin,
                                            DateUtils.format(elecAbnormalData.getEarliestAbnormalTime(), DateUtils.DATE_TIME_PATTERN),
                                            DateUtils.format(elecAbnormalData.getCurrentAbnormalTime(), DateUtils.DATE_TIME_PATTERN));
                                    elecAbnormalData.setWarnInfo(warnInfo);
                                    log.info("注意：电池电压异常告警----{}", warnInfo);
                                }
                                if (daElecTimes != null && (elecAbnormalData.getContinuousAbnormalTimes() >= daElecTimes)) {
                                    String warnInfo = String.format("基站失控：基站%s 电池电压连续%s次低于%s，发生时间段为%s至%s",
                                            heartbeatRecordDO.getBaseStationNum(),
                                            daElecTimes,
                                            daElecMin,
                                            DateUtils.format(elecAbnormalData.getEarliestAbnormalTime(), DateUtils.DATE_TIME_PATTERN),
                                            DateUtils.format(elecAbnormalData.getCurrentAbnormalTime(), DateUtils.DATE_TIME_PATTERN));
                                    elecAbnormalData.setWarnInfo(warnInfo);
                                    log.info("注意：电池电压异常告警----{}", warnInfo);
                                }

                                WarningRecordDO warningRecordDO = new WarningRecordDO();
                                warningRecordDO.setNum("");
                                warningRecordDO.setBaseStationNum(heartbeatRecordDO.getBaseStationNum());
                                warningRecordDO.setWarningDesc(elecAbnormalData.getWarnInfo());
                                warningRecordDO.setWarningTime(elecAbnormalData.getEarliestAbnormalTime());
                                warningRecordDO.setWarningType(AnimalConstant.warning_type_baseStation);
                                warningRecordDO.setRemark1(warningRecordDO.getWarningType() + warningRecordDO.getBaseStationNum() + warningRecordDO.getWarningTime().getTime());
                                if (!AnimalConstant.open.equals(exWarningSetDO.getDialogTipSwitch())) {
                                    warningRecordDO.setHandler(1l);
                                    warningRecordDO.setHandlingTime(new Date());
                                    warningRecordDO.setHandlingResult("弹窗开关未打开，默认已处理");
                                }
                                //warningRecordDao.save(warningRecordDO);
                                //记录到MAP
                                baseStationWarnRecordMap.put(heartbeatRecordDO.getBaseStationNum(), warningRecordDO);

                            } else {
                                log.info("基站{}电池电压低于{},但是未满足所需告警条件，当前电池电压持续异常{}次，当前电池电压持续异常{}分钟，", heartbeatRecordDO.getBaseStationNum(), daElecMin, elecAbnormalData.getContinuousAbnormalTimes(), realElecDuration);
                                log.info("基站{}电池电压低于{}告警需持续异常{}次或者持续异常{}分钟，", heartbeatRecordDO.getBaseStationNum(), daElecMin, daElecTimes, daElecDuration);
                            }
                        } else {//正常数据
                            elecAbnormalData.setEarliestAbnormalTime(null);
                            elecAbnormalData.setContinuousAbnormalTimes(0);
                        }
                    }

                    //004 基站心跳数据未上传
                    if (upLoadDuration != null) {
                        String uploadKey = AnimalConstant.baseStation_upload + heartbeatRecordDO.getBaseStationNum();
                        if (baseStationNonUploadWarnMap.get(uploadKey) == null) {
                            baseStationNonUploadWarnMap.put(uploadKey, new ExWarningDO.NonUploadData());
                        }
                        //基站心跳数据未上传
                        ExWarningDO.NonUploadData nonUploadData =  baseStationNonUploadWarnMap.get(uploadKey);

                        if (nonUploadData.getEarliestUploadTime() == null) {
                            nonUploadData.setEarliestUploadTime(heartbeatRecordDO.getCreateTime());
                        } else {
                            nonUploadData.setEarliestUploadTime(nonUploadData.getCurrentUploadDataTime());
                        }
                        nonUploadData.setCurrentUploadDataTime(heartbeatRecordDO.getCreateTime());
                        nonUploadData.setCurrentData(heartbeatRecordDO);
                        long realUpLoadDuration = (nonUploadData.getCurrentUploadDataTime().getTime() - nonUploadData.getEarliestUploadTime().getTime()) / 1000 / 60;
                        if (nonUploadData.getCurrentUploadDataTime().getTime() - nonUploadData.getEarliestUploadTime().getTime() >= upLoadDuration * 1000 * 60) {

                            String warnInfo = String.format("基站失控：基站%s 连续%s(超过%s)分钟没有上传心跳数据，发生时间段为%s至%s",
                                    heartbeatRecordDO.getBaseStationNum(),
                                    realUpLoadDuration,
                                    upLoadDuration,
                                    DateUtils.format(nonUploadData.getEarliestUploadTime(), DateUtils.DATE_TIME_PATTERN),
                                    DateUtils.format(nonUploadData.getCurrentUploadDataTime(), DateUtils.DATE_TIME_PATTERN));
                            nonUploadData.setWarnInfo(warnInfo);
                            nonUploadData.setWarn(true);
                            log.info("注意：基站心跳数据未上传告警----{}", warnInfo);

                            WarningRecordDO warningRecordDO = new WarningRecordDO();
                            warningRecordDO.setNum("");
                            warningRecordDO.setBaseStationNum(heartbeatRecordDO.getBaseStationNum());
                            warningRecordDO.setWarningDesc(nonUploadData.getWarnInfo());
                            warningRecordDO.setWarningTime(nonUploadData.getEarliestUploadTime());
                            warningRecordDO.setWarningType(AnimalConstant.warning_type_baseStation);
                            warningRecordDO.setRemark1(warningRecordDO.getWarningType() + warningRecordDO.getBaseStationNum() + warningRecordDO.getWarningTime().getTime());
                            if (!AnimalConstant.open.equals(exWarningSetDO.getDialogTipSwitch())) {
                                warningRecordDO.setHandler(1l);
                                warningRecordDO.setHandlingTime(new Date());
                                warningRecordDO.setHandlingResult("弹窗开关未打开，默认已处理");
                            }
                            //warningRecordDao.save(warningRecordDO);
                            //记录到MAP
                            baseStationWarnRecordMap.put(heartbeatRecordDO.getBaseStationNum(), warningRecordDO);

                        }
                    }

                }
            }//end for

            //上传数据只有一条，判断上传时间是否超过了阈值
            for (ExWarningDO.NonUploadData nonUploadData : baseStationNonUploadWarnMap.values()) {
                //item.getEarliestUploadTime().equals(item.getCurrentUploadDataTime())  表示只有一条上传数据
                if (nonUploadData.getEarliestUploadTime().equals(nonUploadData.getCurrentUploadDataTime()) && (now.getTime() - nonUploadData.getEarliestUploadTime().getTime() >= upLoadDuration * 1000 * 60)) {
                    nonUploadData.setCurrentUploadDataTime(now);
                    HeartbeatRecordDO heartbeatRecordDO = (HeartbeatRecordDO)nonUploadData.getCurrentData();
                    long realUpLoadDuration = (now.getTime() - nonUploadData.getEarliestUploadTime().getTime()) / 1000 / 60;
                    String warnInfo = String.format("基站失控：基站%s 连续%s(超过%s)分钟没有上传心跳数据，发生时间段为%s至%s",
                            heartbeatRecordDO.getBaseStationNum(),
                            realUpLoadDuration,
                            upLoadDuration,
                            DateUtils.format(nonUploadData.getEarliestUploadTime(), DateUtils.DATE_TIME_PATTERN),
                            DateUtils.format(nonUploadData.getCurrentUploadDataTime(), DateUtils.DATE_TIME_PATTERN));
                    nonUploadData.setWarnInfo(warnInfo);
                    nonUploadData.setWarn(true);
                    log.info("注意：基站心跳数据上传时间间隔超过阈值告警----{}", warnInfo);

                    WarningRecordDO warningRecordDO = new WarningRecordDO();
                    warningRecordDO.setNum("");
                    warningRecordDO.setBaseStationNum(heartbeatRecordDO.getBaseStationNum());
                    warningRecordDO.setWarningDesc(nonUploadData.getWarnInfo());
                    warningRecordDO.setWarningTime(nonUploadData.getEarliestUploadTime());
                    warningRecordDO.setWarningType(AnimalConstant.warning_type_baseStation);
                    warningRecordDO.setRemark1(warningRecordDO.getWarningType() + warningRecordDO.getBaseStationNum() + warningRecordDO.getWarningTime().getTime());
                    if (!AnimalConstant.open.equals(exWarningSetDO.getDialogTipSwitch())) {
                        warningRecordDO.setHandler(1l);
                        warningRecordDO.setHandlingTime(new Date());
                        warningRecordDO.setHandlingResult("弹窗开关未打开，默认已处理");
                    }
                    //记录到MAP
                    baseStationWarnRecordMap.put(heartbeatRecordDO.getBaseStationNum(), warningRecordDO);
                }
            }//end for

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            List list = baseStationWarnRecordMap.values().stream().collect(Collectors.toList());
            if (list.size() > 0) {
                exWarningRecordDao.batchSave(list);
            }
        }

        //耳标告警
        Map<String, WarningRecordDO> tagWarnRecordMap = new HashMap<String, WarningRecordDO>();
        Map<String, Object> tagAbnormalWarnMap = new HashMap<String, Object>();
        Map<String, ExWarningDO.NonUploadData> tagNonUploadWarnMap = new HashMap<String, ExWarningDO.NonUploadData>();
        try {
            Integer tagWarnQueryTimeSpan = Integer.valueOf(SystemUtil.getSystemParams().get(AnimalConstant.key_name_tag_warn_query_time_span).getParamValue());
            Map<String, Object> params = new HashMap<>();
            params.put("startCreateTime", UtilDate.getDateBefore(now, Calendar.MINUTE, tagWarnQueryTimeSpan));
            params.put("sort", "create_time");
            params.put("order", "asc");
            List<RfidSyncDataDO> list = exRfidSyncDataDao.simpleList(params);

            log.info("耳标数据-数量----list.size()：{}", list.size());
            //耳标电压 异常连续时间 分钟
            Float daElecDuration = exWarningSetDO.getWarningSet().getTag().getDaElecDuration();
            //耳标电压 异常连续时间 次数
            Float daElecTimes = exWarningSetDO.getWarningSet().getTag().getDaElecTimes();
            //耳标最小
            Float daElecMin = exWarningSetDO.getWarningSet().getTag().getDaElecMin();
            log.info("耳标电压告警设置----异常连续时间：{}分钟,异常连续次数：{}次,最小电压：{}", daElecDuration, daElecTimes, daElecMin);

            //基站心跳数据未上传
            Float upLoadDuration = exWarningSetDO.getWarningSet().getTag().getUpLoadDuration();
            log.info("耳标数据未上传告警设置----持续时间：{}分钟", upLoadDuration);

            String dialogTipSwitch = exWarningSetDO.getDialogTipSwitch();
            log.info("耳标告警提示开关：{}", dialogTipSwitch);

            for (int i = 0; i < list.size(); i++) {
                RfidSyncDataDO rfidSyncDataDO = list.get(i);

                //耳标异常数据 告警记录
                WarningRecordDO tagWarnRecord = tagWarnRecordMap.get(rfidSyncDataDO.getNum());
                if (tagWarnRecord == null) {
                    //003 耳标电压
                    //耳标电压 异常连续时间 次数
                    if ((daElecDuration != null || daElecTimes != null) && daElecMin != null) {
                        String elecKey = AnimalConstant.tag_elec + rfidSyncDataDO.getNum();
                        if (tagAbnormalWarnMap.get(elecKey) == null) {
                            tagAbnormalWarnMap.put(elecKey, new ExWarningDO.AbnormalData());
                        }
                        //耳标电压 异常数据
                        ExWarningDO.AbnormalData elecAbnormalData = (ExWarningDO.AbnormalData) tagAbnormalWarnMap.get(elecKey);
                        Integer daElec = rfidSyncDataDO.getSoc();
                        Float daElecFloat = null;
                        //未被记录为连续失控 且 耳标电压不为空  且 耳标电压小于最小电压
                        if (!elecAbnormalData.getWarn() && daElec != null && daElec < daElecMin) {
                            log.info("耳标电压低于{}告警----心跳数据：{}", daElecMin, JSON.toJSONString(rfidSyncDataDO));
                            //最早异常数据
                            if (elecAbnormalData.getEarliestAbnormalTime() == null) {
                                elecAbnormalData.setEarliestAbnormalTime(rfidSyncDataDO.getCreateTime());
                            }
                            //当前异常数据
                            elecAbnormalData.setCurrentAbnormalTime(rfidSyncDataDO.getCreateTime());
                            elecAbnormalData.setContinuousAbnormalTimes(elecAbnormalData.getContinuousAbnormalTimes() + 1);
                            long realElecDuration = (elecAbnormalData.getCurrentAbnormalTime().getTime() - elecAbnormalData.getEarliestAbnormalTime().getTime()) / 1000 / 60;
                            if (daElecDuration != null && (elecAbnormalData.getCurrentAbnormalTime().getTime() - elecAbnormalData.getEarliestAbnormalTime().getTime() >= daElecDuration * 1000 * 60)
                                    || daElecTimes != null && (elecAbnormalData.getContinuousAbnormalTimes() >= daElecTimes)) {

                                elecAbnormalData.setWarn(true);
                                if (daElecDuration != null && (elecAbnormalData.getCurrentAbnormalTime().getTime() - elecAbnormalData.getEarliestAbnormalTime().getTime() >= daElecDuration * 1000 * 60)) {
                                    String warnInfo = String.format("耳标失控：耳标%s电压连续%s分钟（超过%s分钟）低于%s，发生时间段为%s至%s",
                                            rfidSyncDataDO.getNum(),
                                            realElecDuration,
                                            daElecDuration,
                                            daElecMin,
                                            DateUtils.format(elecAbnormalData.getEarliestAbnormalTime(), DateUtils.DATE_TIME_PATTERN),
                                            DateUtils.format(elecAbnormalData.getCurrentAbnormalTime(), DateUtils.DATE_TIME_PATTERN));
                                    elecAbnormalData.setWarnInfo(warnInfo);
                                    log.info("注意：耳标电压异常告警----{}", warnInfo);
                                }
                                if (daElecTimes != null && (elecAbnormalData.getContinuousAbnormalTimes() >= daElecTimes)) {
                                    String warnInfo = String.format("耳标失控：耳标%s电压连续%s次低于%s，发生时间段为%s至%s",
                                            rfidSyncDataDO.getNum(),
                                            daElecTimes,
                                            daElecMin,
                                            DateUtils.format(elecAbnormalData.getEarliestAbnormalTime(), DateUtils.DATE_TIME_PATTERN),
                                            DateUtils.format(elecAbnormalData.getCurrentAbnormalTime(), DateUtils.DATE_TIME_PATTERN));
                                    elecAbnormalData.setWarnInfo(warnInfo);
                                    log.info("注意：耳标电压异常告警----{}", warnInfo);
                                }

                                WarningRecordDO warningRecordDO = new WarningRecordDO();
                                warningRecordDO.setNum(rfidSyncDataDO.getNum());
                                warningRecordDO.setBaseStationNum(rfidSyncDataDO.getBaseStationNum());
                                warningRecordDO.setWarningDesc(elecAbnormalData.getWarnInfo());
                                warningRecordDO.setWarningTime(elecAbnormalData.getEarliestAbnormalTime());
                                warningRecordDO.setWarningType(AnimalConstant.warning_type_tag);
                                warningRecordDO.setRemark1(warningRecordDO.getWarningType() + warningRecordDO.getNum() + warningRecordDO.getWarningTime().getTime());
                                if (!AnimalConstant.open.equals(exWarningSetDO.getDialogTipSwitch())) {
                                    warningRecordDO.setHandler(1l);
                                    warningRecordDO.setHandlingTime(new Date());
                                    warningRecordDO.setHandlingResult("弹窗开关未打开，默认已处理");
                                }
                                //warningRecordDao.save(warningRecordDO);
                                //记录到MAP
                                tagWarnRecordMap.put(rfidSyncDataDO.getNum(), warningRecordDO);

                            } else {
                                log.info("耳标{}电压低于{},但是未满足所需告警条件，当前耳标电压持续异常{}次，当前耳标电压持续异常{}分钟，", rfidSyncDataDO.getNum(), daElecMin, elecAbnormalData.getContinuousAbnormalTimes(), realElecDuration);
                                log.info("耳标{}电压低于{}告警需持续异常{}次或者持续异常{}分钟，", rfidSyncDataDO.getNum(), daElecMin, daElecTimes, daElecDuration);
                            }
                        } else {//正常数据
                            elecAbnormalData.setEarliestAbnormalTime(null);
                            elecAbnormalData.setContinuousAbnormalTimes(0);
                        }
                    }

                    //004 耳标数据未上传
                    if (upLoadDuration != null) {
                        String uploadKey = AnimalConstant.tag_upload + rfidSyncDataDO.getNum();
                        if (tagNonUploadWarnMap.get(uploadKey) == null) {
                            tagNonUploadWarnMap.put(uploadKey, new ExWarningDO.NonUploadData());
                        }
                        //基站心跳数据未上传
                        ExWarningDO.NonUploadData nonUploadData = tagNonUploadWarnMap.get(uploadKey);

                        if (nonUploadData.getEarliestUploadTime() == null) {
                            nonUploadData.setEarliestUploadTime(rfidSyncDataDO.getCreateTime());
                        } else {
                            nonUploadData.setEarliestUploadTime(nonUploadData.getCurrentUploadDataTime());
                        }
                        nonUploadData.setCurrentUploadDataTime(rfidSyncDataDO.getCreateTime());
                        nonUploadData.setCurrentData(rfidSyncDataDO);
                        long realUpLoadDuration = (nonUploadData.getCurrentUploadDataTime().getTime() - nonUploadData.getEarliestUploadTime().getTime()) / 1000 / 60;
                        if (nonUploadData.getCurrentUploadDataTime().getTime() - nonUploadData.getEarliestUploadTime().getTime() >= upLoadDuration * 1000 * 60) {

                            String warnInfo = String.format("耳标失控：耳标%s连续%s(超过%s)分钟没有上传心跳数据，发生时间段为%s至%s",
                                    rfidSyncDataDO.getNum(),
                                    realUpLoadDuration,
                                    upLoadDuration,
                                    DateUtils.format(nonUploadData.getEarliestUploadTime(), DateUtils.DATE_TIME_PATTERN),
                                    DateUtils.format(nonUploadData.getCurrentUploadDataTime(), DateUtils.DATE_TIME_PATTERN));
                            nonUploadData.setWarnInfo(warnInfo);
                            nonUploadData.setWarn(true);
                            log.info("注意：耳标数据未上传告警----{}", warnInfo);

                            WarningRecordDO warningRecordDO = new WarningRecordDO();
                            warningRecordDO.setNum(rfidSyncDataDO.getNum());
                            warningRecordDO.setBaseStationNum(rfidSyncDataDO.getBaseStationNum());
                            warningRecordDO.setWarningDesc(nonUploadData.getWarnInfo());
                            warningRecordDO.setWarningTime(nonUploadData.getEarliestUploadTime());
                            warningRecordDO.setWarningType(AnimalConstant.warning_type_tag);
                            warningRecordDO.setRemark1(warningRecordDO.getWarningType() + warningRecordDO.getNum() + warningRecordDO.getWarningTime().getTime());
                            if (!AnimalConstant.open.equals(exWarningSetDO.getDialogTipSwitch())) {
                                warningRecordDO.setHandler(1l);
                                warningRecordDO.setHandlingTime(new Date());
                                warningRecordDO.setHandlingResult("弹窗开关未打开，默认已处理");
                            }
                            //记录到MAP
                            tagWarnRecordMap.put(rfidSyncDataDO.getNum(), warningRecordDO);
                        }
                    }

                }
            }//end for


            //上传数据只有一条，判断上传时间是否超过了阈值
            for (ExWarningDO.NonUploadData nonUploadData : tagNonUploadWarnMap.values()) {
                //item.getEarliestUploadTime().equals(item.getCurrentUploadDataTime())  表示只有一条上传数据
                if (nonUploadData.getEarliestUploadTime().equals(nonUploadData.getCurrentUploadDataTime()) && (now.getTime() - nonUploadData.getEarliestUploadTime().getTime() >= upLoadDuration * 1000 * 60)) {
                    nonUploadData.setCurrentUploadDataTime(now);
                    RfidSyncDataDO rfidSyncDataDO = (RfidSyncDataDO)nonUploadData.getCurrentData();
                    long realUpLoadDuration = (now.getTime() - nonUploadData.getEarliestUploadTime().getTime()) / 1000 / 60;
                    String warnInfo = String.format("耳标失控：耳标%s连续%s(超过%s)分钟没有上传心跳数据，发生时间段为%s至%s",
                            rfidSyncDataDO.getNum(),
                            realUpLoadDuration,
                            upLoadDuration,
                            DateUtils.format(nonUploadData.getEarliestUploadTime(), DateUtils.DATE_TIME_PATTERN),
                            DateUtils.format(nonUploadData.getCurrentUploadDataTime(), DateUtils.DATE_TIME_PATTERN));
                    nonUploadData.setWarnInfo(warnInfo);
                    nonUploadData.setWarn(true);
                    log.info("注意：耳标数据上传时间间隔超过阈值告警----{}", warnInfo);

                    WarningRecordDO warningRecordDO = new WarningRecordDO();
                    warningRecordDO.setNum(rfidSyncDataDO.getNum());
                    warningRecordDO.setBaseStationNum(rfidSyncDataDO.getBaseStationNum());
                    warningRecordDO.setWarningDesc(nonUploadData.getWarnInfo());
                    warningRecordDO.setWarningTime(nonUploadData.getEarliestUploadTime());
                    warningRecordDO.setWarningType(AnimalConstant.warning_type_tag);
                    warningRecordDO.setRemark1(warningRecordDO.getWarningType() + warningRecordDO.getNum() + warningRecordDO.getWarningTime().getTime());
                    if (!AnimalConstant.open.equals(exWarningSetDO.getDialogTipSwitch())) {
                        warningRecordDO.setHandler(1l);
                        warningRecordDO.setHandlingTime(new Date());
                        warningRecordDO.setHandlingResult("弹窗开关未打开，默认已处理");
                    }
                    //记录到MAP
                    tagWarnRecordMap.put(rfidSyncDataDO.getNum(), warningRecordDO);
                }
            }//end for

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            List list = tagWarnRecordMap.values().stream().collect(Collectors.toList());
            if (list.size() > 0) {
                exWarningRecordDao.batchSave(list);
            }
        }
        pushWarnInfoToWeb();
    }

    //推送预警信息到页面
    @Override
    public void pushWarnInfoToWeb() {
        try {
            ExWarningSetDO exWarningSetDO = SystemUtil.getWarningSets().get(null);
            if (AnimalConstant.open.equals(exWarningSetDO.getDialogTipSwitch())) {
                Integer tagWarnQueryTimeSpan = Integer.valueOf(SystemUtil.getSystemParams().get(AnimalConstant.key_name_query_warn_time_quantum).getParamValue());
                Map<String, Integer> map = exWarningRecordDao.queryAlarmAmount(UtilDate.getDateBefore(new Date(), Calendar.MINUTE, tagWarnQueryTimeSpan));
                Object allSum = map.get("allSum");
                if ((long) allSum > 0) {
                    template.convertAndSend("/topic/warn", map);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //处理预警
    @Override
    public void handleWarn() {
        WarningRecordDO warningRecordDO = new WarningRecordDO();
        warningRecordDO.setHandler(ShiroUtils.getUser().getUserId());
        warningRecordDO.setHandlingTime(new Date());
        warningRecordDO.setHandlingResult("已处理");
        //再加五分钟
        Integer tagWarnQueryTimeSpan = Integer.valueOf(SystemUtil.getSystemParams().get(AnimalConstant.key_name_query_warn_time_quantum).getParamValue()) + 5;
        warningRecordDO.setWarningTime(UtilDate.getDateBefore(warningRecordDO.getHandlingTime(), Calendar.MINUTE, tagWarnQueryTimeSpan));
        exWarningRecordDao.handleWarning(warningRecordDO);
    }
}
